/**
 *
 */
package co.fitstart.payment.web.handler.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.utils.SignatureUtils;
import com.demo2do.core.utils.StringUtils;

import co.fitstart.payment.entity.app.App;
import co.fitstart.payment.entity.channel.Channel;
import co.fitstart.payment.entity.request.RequestRecord;
import co.fitstart.payment.web.handler.OrderHandler;

/**
 * @author lute
 *
 */
@Component("orderHandler")
public class OrderHandlerImpl implements OrderHandler {

    private static final Logger logger = LoggerFactory.getLogger(OrderHandlerImpl.class);

    /* (non-Javadoc)
     * @see co.fitstart.payment.web.handler.OrderHandler#synchronizeOrderStatus(co.fitstart.payment.entity.app.App, co.fitstart.payment.entity.request.RequestRecord, co.fitstart.payment.entity.channel.Channel, int, java.lang.String)
     */
    public boolean synchronizeOrderStatus(App app, RequestRecord requestRecord, Channel channel, int amount, String payTimeString) {

        Result result = new Result();

        // Get order number, customer id and notify url
        String orderNo = requestRecord.getOrderNo();
        String customerId = requestRecord.getCustomerId();
        String notifyUrl = requestRecord.getNotifyUrl();

        Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("appid", app.getAppid());
        parameters.put("channel", channel.getName());
        parameters.put("order_no", orderNo);
        parameters.put("customer_id", customerId);
        parameters.put("amount", String.valueOf(amount));
        parameters.put("pay_time", payTimeString);
        parameters.put("request_no", requestRecord.getRequestNo());

        String queryString = StringUtils.toSortedQueryString(parameters) + "&key=" + app.getAppsecret();
        String signature = SignatureUtils.makeMD5Signature(queryString).toUpperCase();
        parameters.put("signature", signature);

        logger.trace("OrderHandlerImpl#synchronizeOrderStatus() - Get encrpted signature [{}].", signature);
        logger.trace("OrderHandlerImpl#synchronizeOrderStatus() - Going to call notify url [{}] with order number [{}], customer id [{}], amount [{}], pay time [{}], request number [{}] and signature [{}].", notifyUrl, orderNo, customerId, amount, payTimeString, requestRecord.getRequestNo(), signature);

        String content = JsonUtils.toJsonString(parameters);

        try {

            Response response = Request.Post(notifyUrl)
                                       .bodyString(content, ContentType.APPLICATION_JSON)
                                       .connectTimeout(10000)
                                       .socketTimeout(10000)
                                       .execute();

            String body = response.returnContent().asString(Consts.UTF_8);
            logger.trace("OrderHandlerImpl#synchronizeOrderStatus() - Get syncOrder response body [{}]", body);
            
            result = JSON.parseObject(body, Result.class);

        } catch (IOException e) {
            logger.error("OrderHandlerImpl#synchronizeOrderStat() - Synchronizing order status occurs IO exception.");
            e.printStackTrace();
        }

        return result.isValid();
    }

}
